package com.wombatsoft.gtw.xmpp;

import java.util.ArrayList;
import java.util.Collection;

import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;

import android.util.Log;

import com.wombatsoft.gtw.Contact;
import com.wombatsoft.gtw.util.Configuration;

public class ConnectionManager {
	private static ConnectionManager instance = new ConnectionManager();
	private Connection connection;
	private Roster roster;

	private ConnectionManager() {
		this.connection = new XMPPConnection(new ConnectionConfiguration(
				Configuration.TALK_SERVER_HOST, Configuration.TALK_SERVER_PORT,
				"gmail.com"));
	}

	public static ConnectionManager getInstance() {
		return instance;
	}

	public Boolean login(String user, String password) {
		Boolean result = Boolean.FALSE;

		if (!connection.isConnected()) {

			try {
				connection.connect();

				Log.d(this.getClass().getName(),
						String.format("Connected to server %s",
								connection.getHost()));

				result = Boolean.TRUE;

			} catch (XMPPException e) {
				Log.e(this.getClass().getName(), e.getMessage(), e);
				result = Boolean.FALSE;
			}
		} else {
			result = Boolean.TRUE;
		}

		if (!connection.isAuthenticated()) {
			try {
				connection.login(user, password);

				Log.d(this.getClass().getName(),
						String.format("%s authenticated", connection.getUser()));

				Presence presence = new Presence(Presence.Type.available);
				connection.sendPacket(presence);

				roster = connection.getRoster();

				result = Boolean.TRUE;
			} catch (XMPPException e) {
				Log.e(this.getClass().getName(), e.getMessage(), e);
				result = Boolean.FALSE;
			}
		} else {
			result = Boolean.TRUE;
		}

		return result;
	}

	public void logout() {
		connection.disconnect();
	}

	public ArrayList<Contact> getContactList() {
		ArrayList<Contact> contactList = new ArrayList<Contact>();

		if (roster != null) {
			Collection<RosterEntry> rosterCollection = roster.getEntries();
			Presence presence;

			for (RosterEntry re : rosterCollection) {
				presence = roster.getPresence(re.getUser());

				if (presence.isAvailable()) {
					Contact c = new Contact();

					if (re.getName() == null || re.getName().trim().equals("")) {
						c.setName(re.getUser());
					} else {
						c.setName(re.getName());
					}

					if (presence.getMode() == null) {
						c.setPresence(Contact.Presence.AVAILABLE);
					} else if (presence.getMode().equals(Presence.Mode.chat)) {
						c.setPresence(Contact.Presence.CHAT);
					} else if (presence.getMode().equals(Presence.Mode.away)
							|| presence.getMode().equals(Presence.Mode.xa)) {
						c.setPresence(Contact.Presence.AWAY);
					} else if (presence.getMode().equals(Presence.Mode.dnd)) {
						c.setPresence(Contact.Presence.DND);
					} else {
						c.setPresence(Contact.Presence.AVAILABLE);
					}

					contactList.add(c);
				}
			}
		}

		return contactList;
	}

	public Roster getRoster() {
		return roster;
	}

}
